
#include "stepcount.h"
/*==============================================================================*/
/*****************************Defines********************************************/
/*==============================================================================*/

/* Threshold limits*/

/* Threshold limits*/

#define WALKING_LOWER_LIMIT                     100>>V_DivideFactor_U8R /**< Composite Lower Threshold for Walk step*/

#define WALKING_UPPER_LIMIT                     400>>V_DivideFactor_U8R /**< Composite Upper Threshold for Walk step*/

#define LAZY_WALKING_LOWER_LIMIT_Robust         50>>V_DivideFactor_U8R /**< Composite Lower Threshold for Lazy Walk step*/

#define LAZY_WALKING_LOWER_LIMIT_NoRobust       32>>V_DivideFactor_U8R /**< Composite Lower Threshold for Lazy Walk step*/

#define LAZY_WALKING_UPPER_LIMIT                160>>V_DivideFactor_U8R /**< Composite Upper Threshold for Lazy Walk step*/


#define JOG_LOWER_LIMIT                         100>>V_DivideFactor_U8R/**< Composite Lower Threshold for Jog step */

#define JOG_UPPER_LIMIT                         1200>>V_DivideFactor_U8R/**< Composite Upper Threshold for Jog step*/



#define C_SensorNoiseLevel_U8X                 16>>V_DivideFactor_U8R /**< Variation Of Acceleration Value When kept idle */

/*******************************Trend limits*************************************/


#define WALKING_CYCLE_LOWER_LIMIT               5/**<Trend cycle lower limit for walking*/

#define WALKING_CYCLE_UPPER_LIMIT               21/**< Trend cycle upper limit for walking*/

#define LAZY_WALKING_CYCLE_LOWER_LIMIT          10/**< Trend cycle upper limit for lazy walking*/

#define LAZY_WALKING_CYCLE_UPPER_LIMIT          32/**< Trend cycle upper limit for lazy walking*/

#define JOG_CYCLE_LOWER_LIMIT                   4/**< Trend cycle lower limit for jogging*/

#define JOG_CYCLE_UPPER_LIMIT                   15/**< Trend cycle upper limit for jogging*/

#define MAX_COUNT_DIFFERENCE                    3/**< Difference between 2 adjacent steps*/

/***************************Count Step to Step Limits***************************/

#define C_LazyWalkStepToStepLowerLimit_U8X      18 /**< Count step to step lower limit for lazy walk*/
#define C_LazyWalkStepToStepUpperLimit_U8X      30 /**< Count step to step upper limit for lazy walk*/
#define C_WalkStepToStepLowerLimit_U8X           7 /**< Count step to step lower limit for walk*/
#define C_WalkStepToStepUpperLimit_U8X          17 /**< Count step to step upper limit for walk*/
#define C_JogStepToStepLowerLimit_U8X            7 /**< Count step to step lower limit for Jog*/
#define C_JogStepToStepUpperLimit_U8X           17 /**< Count step to step upper limit for Jog*/
/****************************Mode definition*************************************/


#define MODE_DETECTION                          0/**< First 4 steps yet to be made*/

#define MODE_COUNTING                           1/**< Walking mode (made 4 steps)*/

#define MODE_SLEEPING                           2/**< Sleeping mode*/

#define M_Walk_U8X                              (char)0x01    /**< Mask Bit for Walk*/
#define M_SlowWalk_U8X                          (char)0x02    /**< Mask Bit for Slow Walk*/
#define M_Jog_U8X                               (char)0x04    /**< Mask Bit for Jog*/

#define M_ModeDetection_U8X                     (char)0x01    /**< Mask Bit for Detection Mode*/
#define M_ModeCounting_U8X                      (char)0x02    /**< Mask Bit for Counting Mode*/
#define M_AlgoReset_U8X                         (char)0x04    /**< Mask Bit for Algo reset*/


#define M_Qualified_U8X                       (char)0x08    /**< Mask Bit for Qualified Step*/
#define M_UnQualified_U8X                     (char)0x10    /**< Mask Bit for UnQualified Step*/
#define M_PositiveTrend_U8X                   (char)0x20    /**< Mask Bit for Positive Trend Change*/
#define M_NegativeTrend_U8X                   (char)0x40    /**< Mask Bit for Negative Trend Change*/



#define M_DisableRobustness_U8X               (char)0x80    /**< Mask Bit for Disable robustness feature*/




/****************************Macros dcifing the step Nature**********************/

/** \brief Macro Deciding Lazy walk step
*/
#define IS_LAZY_WALK_STEP(resultDiff_i16) \
        ((resultDiff_i16 >= V_LazyWalkLowerLimit_U8R &&  \
                resultDiff_i16 <= LAZY_WALKING_UPPER_LIMIT) && \
        (s_sampleCountForCycle_i16 >= LAZY_WALKING_CYCLE_LOWER_LIMIT && \
                s_sampleCountForCycle_i16 <= LAZY_WALKING_CYCLE_UPPER_LIMIT))

/** \brief Macro deciding Walk step
*/
#define IS_WALK_STEP(resultDiff_i16) \
        ((resultDiff_i16 >= WALKING_LOWER_LIMIT &&  \
                resultDiff_i16 <= WALKING_UPPER_LIMIT) && \
        (s_sampleCountForCycle_i16 >= WALKING_CYCLE_LOWER_LIMIT && \
                s_sampleCountForCycle_i16 <= WALKING_CYCLE_UPPER_LIMIT))

/** \brief Macro deciding Jog step
*/
#define IS_JOG_STEP(resultDiff_i16) \
        ((resultDiff_i16 >= JOG_LOWER_LIMIT &&  \
                resultDiff_i16 <= JOG_UPPER_LIMIT) && \
        (s_sampleCountForCycle_i16 >= JOG_CYCLE_LOWER_LIMIT && \
                s_sampleCountForCycle_i16 <= JOG_CYCLE_UPPER_LIMIT))

/*================================================================================*/
/* EasyCASE - */
#define C_FilterTaps_U8X                      (char)24 /**< Filter taps*/
#define C_Q15ConversionFactor_U8X             (char)15 /**< Division Factor for Q 15*/
#define C_Clear_U8X                           (char)0 /**<For clearing to  0*/
/* EasyCASE - */
#define C_CountZero_U8X                             (char)0 /**<For Counter purpose 0*/
#define C_CountOne_U8X                              (char)1 /**<For Counter purpose 1*/
/* EasyCASE - */
#define C_DetectionModeTimeOut_U8X          (char)70 /**<Detection Mode time out upper limit (2.8 seconds)*/
#define C_CountingModeTimeOut_U8X          (char)100 /**<Counting Mode time out upper limit (4 seconds)*/
#define C_ErrorCountLimit_U8X              (char)3  /**<Limit for error count*/
#define C_CorrectionCountLimit_U8X         (char)3  /**<Limit for Correction count*/
#define C_InterStepCountLimit_U8X          (char)9  /**<Limit for Inter count*/
#define C_InterStepCountLimitNoRobustness  (char)3  /**<Limit for Inter count*/
/* EasyCASE ) */
/* EasyCASE ( 51
   Variable Decleration */
/*==============================================================================*/
/***************************Global Variable Decleration**************************/
/*==============================================================================*/
/**\brief Holds the pedometer activity \n
*/
static unsigned char V_Activity_U8;
/**\brief holds the mode \n
*/
//static short    gs_mode;
/**\brief Holds last reset value \n
*/
static unsigned long gs_stepCount_i32;

 /**\brief Variable holds the division factor for the threshold
*/
static unsigned char V_DivideFactor_U8R;

 /**\brief Variable holds the Status Flags used
*/
static unsigned char V_StatusFlags_U8R;
/* \brief Holds the 26 input values to the filter \n
*/
static short gs_CompositeFilter[C_FilterTaps_U8X];

/* \brief Holds the lazy walk lower limit threshold \n
*/
static unsigned char V_LazyWalkLowerLimit_U8R =0;

/* \brief Holds the Filter coefficients for 0.24 in Q15 format \n
*/
/* EasyCASE - */
/* EasyCASE < */
static const short gc_CompositeFilterCoeff[C_FilterTaps_U8X] =
{
58,
134,
173,
45,
-324,
-802,
-999,
-422,
1192,
3614,
6078,
7637,
7637,
6078,
3614,
1192,
-422,
-999,
-802,
-324,
45,
173,
134,
58
};
/* EasyCASE > */
/* EasyCASE ) */
/* EasyCASE ( 50
   Local Function Decleration */
/*==============================================================================*/
/*********************************Local function Declaration*********************/
/*==============================================================================*/

static void trendFinder(short, short*);
static short getAbsoluteShort(short f_val_i16);
/* EasyCASE ) */
/* EasyCASE ) */
/* EasyCASE ( 46
   APIS */
/* EasyCASE ( 3
   getStepCount */
/* EasyCASE F */
/**
  \brief This function will return the number of steps counted to the calling function.
  \param None
  \return Number of steps counted
*/

unsigned long getStepCount()
   {
   /*
   **
   *********************************************************************************
     Function Name : unsigned long getStepCount()
     Input         : None
     Output        : Number of step counted
     Scope         : Global
   
     Detailed Description:
       This function will return gs_stepCount_i32 the number of steps counted to the
       calling function
   *********************************************************************************
   **
   */
     /* Return the number of steps counted */
   return (gs_stepCount_i32 );
   }
/* EasyCASE ) */
/* EasyCASE ( 225
   stopDetection */
/* EasyCASE F */
/**
  \brief This function will put the Pedometer Algorithm to Sleep mode.
  \param None
  \return None
*/
void stopDetection()
   {
   /*
   **
   *********************************************************************************
     Function Name   : void stopDetection()
     Input           : None
     Output          : None
     Scope           : Global
     
     Detailed Description:
       This function will set the Mode of the pedometer gs_mode as MODE_SLEEPING
   *********************************************************************************
   **
   */ 
   /*All flags except Robustness Flag resetted*/    
   V_StatusFlags_U8R = (V_StatusFlags_U8R & M_DisableRobustness_U8X);
   }
/* EasyCASE ) */
/* EasyCASE ( 226
   startDetection */
/* EasyCASE F */
/**
  \brief This function will start the Pedometer Algorithm if pedometer is in 
  sleep mode. If Pedometer Algorithm is running already, It will be restarted by
  this function and step count will be reset.By default the normal human activity
  detection is enabled
  \param None
  \return None
*/

void startDetection()
   {
   /*
   **
   *********************************************************************************
     Function Name : void startDetection()
     
     Input         : None
     Output        : None
     Scope         : Global
     
     Detailed Description:
       This function will set the mode as detection mode. If this function is called
       in between the program this function will reset all the step count values.  
   *********************************************************************************
   **
   */       /*All flags except robustness cleared*/
            V_StatusFlags_U8R = (V_StatusFlags_U8R & M_DisableRobustness_U8X);
           /* Set the Previous data count as 1 */
            V_StatusFlags_U8R |= M_AlgoReset_U8X;;
           /* Set the mode as Detection Mode */
            V_StatusFlags_U8R |= M_ModeDetection_U8X;;
   }
/* EasyCASE ) */
/* EasyCASE ( 232
   resetStepCount */
/* EasyCASE F */
/**
  \brief Thsi API will just reset the step count to zero. Pedometer Algorithm mode
  is not affected by this function.
  \param  None
  \return None
*/
void resetStepCount()
   {
   /*
   **
   *********************************************************************************
     Function Name   : void resetStepCount()
     Input           : None
     Output          : None
     Scope           : Global
     
     Detailed Description:
       Thsi API will reset the step count gs_stepCount_i32 to zero and set the 
       gs_resetPrevData previous data count as 1
   *********************************************************************************
   **
   */ 
       /* Reset the number of step counted to 0 */
       gs_stepCount_i32 = C_Clear_U8X;
       /*All flags except Robustness resetted*/
       V_StatusFlags_U8R = (V_StatusFlags_U8R & M_DisableRobustness_U8X);
       /* Set the previous data as 1 */
        V_StatusFlags_U8R|=(M_AlgoReset_U8X|M_ModeDetection_U8X);
   }
/* EasyCASE ) */
/* EasyCASE ( 8
   processAccelarationData */
/* EasyCASE F */
/**
  \brief  This API calculates Composite value from  X,Y,Z Axis acceleration
  values and updates the step count. It also classifies the type of step
  whether it is a Jog/Walk/Slow Walk step. This function returns the calculated
  composite value.
  \param short f_x_i16 : X-Axis acceleration value from the sensor \n
         short f_y_i16 : Y-Axis acceleration value from the sensor \n
         short f_z_i16 : Z-Axis acceleration value from the sensor \n
  \return Composite value
*/
/*
**********************************************************************************************
  Function Name   : short processAccelarationData(short f_x_i16, short f_y_i16, short f_z_i16)
  Input           : short f_x_i16
                    short f_y_i16
                    short f_z_i16
  Output          : Composite value
  Scope           : Global

  Detailed description :
    Variables:
        short f_x_i16 : X-Axis acceleration value from the sensor
        short f_y_i16 : Y-Axis acceleration value from the sensor
        short f_z_i16 : Z-Axis acceleration value from the sensor

  Description:
        This API gets the X,Y,Z Axis values from the sensor and calculates the
        composite and the average composite value. This API also takes care whether
        the step is a walking step, jogging step , slow walking step  and
         stores the corresponding step count values.
*********************************************************************************************
**
*/

short processAccelarationData(short f_x_i16, short f_y_i16, short f_z_i16)
   {
	   /* EasyCASE ( 23
	      Variable Declerations */
		/* Holds the steps counted while not in counting */
	   static char     s_interStepCount_i8=0;
	   /* 0 if there is no correction. correction value if there needs to be a correction */
	   static char     s_correctionCount_i8=0;
	   /* Holds the composite high for the step cycle */
	   static short    s_resultHigh_i16=0x7FFF;
	   /* Holds the sample counts between trend changes */
	   static char    s_sampleCountForCycle_i16=0;
	   /* Holds the time count between second last & last step */
	   static char    s_countStepToStepPrev1_i16=0;
	   /* Holds the time count between third last & second last step */
	   static char     s_countStepToStepPrev2_i16=0;
	   /* Holds the time count between last & this step */
	   static char    gs_countStepToStep_i16=0;
	   /*Holds error count between 2 steps*/
	   static char v_ErrorCount_u8=0;
	   /*Holds the count between two consecutive counts*/
	   static char s_ModeTimer_i8=0;
	   
	   /*Holds prev Result Diff*/
	   static short v_PreResultDiff_s16r=0;
	   /*Holds the previous activity type*/
	   static char v_PreviousActivity_u8=0;
	   /* Initialise the composite value to 0 */
	   short  composite_i16;
	   
	   /* Initialise the filter result value to 0 */
	   long FilterResult_l32;
	   /*brief Used to hold index for filtering \n*/
	    byte gs_FilterIndex;
	   /*The previous status are stored*/
	    static char v_PreStatusFlags_u8r=0;
	   /* EasyCASE ) */
	   /* EasyCASE ( 24
	      Mode is sleeping? */
	   /* Check whether the mode is sleeping mode */
	   if (V_StatusFlags_U8R & (M_ModeDetection_U8X|M_ModeCounting_U8X))
	      {
	      }
	   else
	      {
	      /* Return 0 */
	      return 0;
	      }
	   /* EasyCASE ) */
	   /* EasyCASE ( 25
	      Reset Previous data */
	   if (V_StatusFlags_U8R & M_AlgoReset_U8X)
	      {
	      /* Set the reset the previous data as 0 */
	      V_StatusFlags_U8R &= ~M_AlgoReset_U8X;
	      /* Holds the steps counted while not in counting */
	      s_interStepCount_i8=C_Clear_U8X;
	      /* 0 if there is no correction. correction value if there needs to be a correction */
	      s_correctionCount_i8=C_Clear_U8X;
	      /* Holds the composite high for the step cycle */
	      s_resultHigh_i16=0x7FFF;
	      /* Holds the sample counts between trend changes */
	      s_sampleCountForCycle_i16=C_Clear_U8X;
	      /* Holds the time count between second last & last step */
	      s_countStepToStepPrev1_i16=C_Clear_U8X;
	      /* Holds the time count between third last & second last step */
	      s_countStepToStepPrev2_i16=C_Clear_U8X;
	      /* Holds the time count between last & this step */
	      gs_countStepToStep_i16=C_Clear_U8X;
	      /*Holds the previous activity type*/
	      v_PreviousActivity_u8=C_Clear_U8X;
	      /*Holds error count between 2 steps*/
	      v_ErrorCount_u8=C_Clear_U8X;
	      /*Holds the count between two consecutive counts*/
	      s_ModeTimer_i8=C_Clear_U8X;
	      /*Holds prev Result Diff*/
	      v_PreResultDiff_s16r=C_Clear_U8X;
	      /*The variable holding filter result are cleared*/
	      FilterResult_l32=C_Clear_U8X;
	      for (gs_FilterIndex=0;gs_FilterIndex<C_FilterTaps_U8X;gs_FilterIndex++)
	         {
	         gs_CompositeFilter[gs_FilterIndex] = C_Clear_U8X;
	         }
	      }
	   /* EasyCASE ) */
	   /* EasyCASE ( 213
	      Change in Robstness feature */
	   if (/*Check whether robustness feature status changed*/
	       ((V_StatusFlags_U8R & M_DisableRobustness_U8X)!=
	        (v_PreStatusFlags_u8r & M_DisableRobustness_U8X)))
	      {
	      /*Robustness feature got changed So Clear Temporary counts */
	      s_correctionCount_i8=0;
	      s_interStepCount_i8=0;
	      V_StatusFlags_U8R &=~(M_Qualified_U8X|M_UnQualified_U8X);
	      s_ModeTimer_i8 = 0;
	      V_StatusFlags_U8R |=M_ModeDetection_U8X;
	      V_StatusFlags_U8R &=~M_ModeCounting_U8X;
	      }
	   /* EasyCASE ) */
	   /* EasyCASE ( 118
	      Counts And Composite Calculation */
	   /* Increment the cycle and step to step counters */
	   s_sampleCountForCycle_i16++;
	   /* Increment the step to step count */
	   gs_countStepToStep_i16++;
	   /* Calculate the composite acceleration component value */
	   composite_i16 = getAbsoluteShort(f_x_i16) + getAbsoluteShort(f_y_i16) + getAbsoluteShort(f_z_i16);
	   /* EasyCASE - */
	   /*Increment Count Mode Elapse Timer*/
	   s_ModeTimer_i8++;
	   for (gs_FilterIndex=C_FilterTaps_U8X-C_CountOne_U8X;gs_FilterIndex>C_CountZero_U8X;gs_FilterIndex--)
	      {
	      gs_CompositeFilter[gs_FilterIndex] = gs_CompositeFilter[gs_FilterIndex-C_CountOne_U8X];
	      }
	   gs_CompositeFilter[C_CountZero_U8X] = composite_i16;
	   /*Wait till atleast 24 values are received.*/
	   /*The variable get cleared*/
	   FilterResult_l32=C_Clear_U8X;
	   for (gs_FilterIndex=C_CountZero_U8X;gs_FilterIndex<C_FilterTaps_U8X;gs_FilterIndex++)
	      {
	      FilterResult_l32 = FilterResult_l32 + (long)((long)gs_CompositeFilter[(C_FilterTaps_U8X-C_CountOne_U8X)-gs_FilterIndex]
	      *(long)gc_CompositeFilterCoeff[gs_FilterIndex]);
	      }
	   /* Divide by 32768 to compensate Q15 format multiplication.*/
	   composite_i16 = (short)(FilterResult_l32>>C_Q15ConversionFactor_U8X);
	   
	   /****************************Filtering end************************************************************/
	   /* Analyse the cycle trend for steps */
	    trendFinder(composite_i16, &composite_i16);
	   /* Check whether the trend is positive or negative */
	   /* EasyCASE ) */
	   /* EasyCASE ( 16
	      Human Activity */
	   /* Check whether the trend is positive or negative */
	   if (V_StatusFlags_U8R & M_NegativeTrend_U8X)
	      {
	      /* Acceleration for step start */
	      s_resultHigh_i16 = composite_i16;
	      }
	   else
	      {
	      if (V_StatusFlags_U8R & M_PositiveTrend_U8X)
	         {
	         V_StatusFlags_U8R &=~(M_Qualified_U8X|M_UnQualified_U8X);
	         composite_i16 = s_resultHigh_i16 - composite_i16;
	         /* Clear the Activity */
	         V_Activity_U8 = C_Clear_U8X;
	         /* Check whether the step is walk step */
	         /* EasyCASE ( 14
	            Lazy Walk */
	         /* Check whether the step is lazy walk step */
	         if (IS_LAZY_WALK_STEP(composite_i16))
	            {
	            if (((gs_countStepToStep_i16 > C_LazyWalkStepToStepLowerLimit_U8X) 
	                && (gs_countStepToStep_i16 < C_LazyWalkStepToStepUpperLimit_U8X)))
	               {
	               V_StatusFlags_U8R |= M_Qualified_U8X;
	               }
	            else
	               {
	               V_StatusFlags_U8R |= M_UnQualified_U8X;
	               }
	            /* Slow activity */
	            V_Activity_U8 |= M_SlowWalk_U8X;
	            }
	         /* EasyCASE ) */
	         /* EasyCASE ( 11
	            Walk */
	         if (IS_WALK_STEP(composite_i16))
	            {
	            if (((getAbsoluteShort(gs_countStepToStep_i16 -  s_countStepToStepPrev1_i16) <= MAX_COUNT_DIFFERENCE) ||
	                ( getAbsoluteShort(gs_countStepToStep_i16 -  s_countStepToStepPrev2_i16) <=MAX_COUNT_DIFFERENCE) )&&
	                ((gs_countStepToStep_i16 > C_WalkStepToStepLowerLimit_U8X)
	                 && (gs_countStepToStep_i16 < C_WalkStepToStepUpperLimit_U8X)))
	               {
	               V_StatusFlags_U8R |= M_Qualified_U8X;
	               }
	            else
	               {
	               V_StatusFlags_U8R |= M_UnQualified_U8X;
	               }
	            /* Medium activity */
	            V_Activity_U8 |= M_Walk_U8X;
	            }
	         /* EasyCASE ) */
	         /* EasyCASE ( 12
	            Jog */
	         /* Check whether the step is Jog step */
	         if (IS_JOG_STEP(composite_i16))
	            {
	            if (((getAbsoluteShort(gs_countStepToStep_i16 -  s_countStepToStepPrev1_i16) <= MAX_COUNT_DIFFERENCE) ||
	                ( getAbsoluteShort(gs_countStepToStep_i16 -  s_countStepToStepPrev2_i16) <=MAX_COUNT_DIFFERENCE) )&&
	                ((gs_countStepToStep_i16 > C_JogStepToStepLowerLimit_U8X) && 
	                (gs_countStepToStep_i16 < C_JogStepToStepUpperLimit_U8X)))
	               {
	               V_StatusFlags_U8R |= M_Qualified_U8X;
	               }
	            else
	               {
	               V_StatusFlags_U8R |= M_UnQualified_U8X;
	               }
	            /* Brisk activity */
	            V_Activity_U8 |= M_Jog_U8X;
	            }
	         /* EasyCASE ) */
	         /* EasyCASE ( 15
	            Step counting */
	         /* EasyCASE ( 217
	            Time out in Detection */
	         if ((s_ModeTimer_i8>C_DetectionModeTimeOut_U8X)&&( V_StatusFlags_U8R&M_ModeDetection_U8X)
	             /* No steps for 2.8 seconds in Detection Mode */)
	            {
	            s_ModeTimer_i8=C_Clear_U8X;
	            if (((V_StatusFlags_U8R & M_DisableRobustness_U8X)==0))
	               {
	               /* No activity in detection mode; so clear the Temporary step count*/
	               s_correctionCount_i8=C_Clear_U8X;
	               s_interStepCount_i8=C_Clear_U8X;
	               V_StatusFlags_U8R &=~(M_Qualified_U8X|M_UnQualified_U8X);
	               v_ErrorCount_u8=C_Clear_U8X;
	               }
	            }
	         /* EasyCASE ) */
	         /* EasyCASE ( 218
	            Time out in Counting */
	         if ((s_ModeTimer_i8>C_CountingModeTimeOut_U8X)&&( V_StatusFlags_U8R&M_ModeCounting_U8X)
	             /* No steps for 4 seconds in Count Mode*/)
	            {
	            s_ModeTimer_i8=C_Clear_U8X;
	            if (((V_StatusFlags_U8R & M_DisableRobustness_U8X)==0))
	               {
	               /* No activity in counting mode; so clear the Temporary step count*/
	               s_correctionCount_i8=C_Clear_U8X;
	               V_StatusFlags_U8R &=~(M_Qualified_U8X|M_UnQualified_U8X);
	               v_ErrorCount_u8=C_Clear_U8X;
	                V_StatusFlags_U8R|=M_ModeDetection_U8X;
	                V_StatusFlags_U8R&=~M_ModeCounting_U8X;
	               }
	            }
	         /* EasyCASE ) */
	         if (/*Check whether step is valid or not*/
	             ((V_StatusFlags_U8R & (M_Qualified_U8X|M_UnQualified_U8X))!=0))
	            {
	            /*If there is change in activity and the current result diff are
	            greater than certain "Threshold" then  temporary counts are cleared .
	            Threshold=(Largest of Current Result Diff and previous Result Diff)/2 .
	            This is applicable in detection mode*/
	            /* EasyCASE ( 220
	               Activity Monitor */
	            if (((v_PreviousActivity_u8 & V_Activity_U8)==C_Clear_U8X) &&
	                (v_PreviousActivity_u8 !=C_Clear_U8X) &&
	                ( V_StatusFlags_U8R&M_ModeDetection_U8X)&&
	                (((getAbsoluteShort(composite_i16-v_PreResultDiff_s16r))<<C_CountOne_U8X)>
	                ((composite_i16>v_PreResultDiff_s16r)?composite_i16:v_PreResultDiff_s16r))
	                &&((V_StatusFlags_U8R & M_DisableRobustness_U8X)==0))
	               {
	               /* Activities differ in Detection state;  So clear
	               the temporary step count*/
	               s_interStepCount_i8 = C_Clear_U8X;
	               s_correctionCount_i8=C_Clear_U8X;
	               V_StatusFlags_U8R &=~(M_Qualified_U8X|M_UnQualified_U8X);
	               }
	            /* EasyCASE ) */
	            /*Stores the current Activity Type*/
	            v_PreviousActivity_u8=V_Activity_U8;
	            /*Stores the current result Diff*/
	            v_PreResultDiff_s16r=composite_i16;
	            /*Error count cleared*/
	            v_ErrorCount_u8=C_Clear_U8X;
	            /*Reset the Mode Timer*/
	            s_ModeTimer_i8=C_Clear_U8X;
	            /* EasyCASE - */
	            /* Check whether the  step is Qualified */
	            if (V_StatusFlags_U8R & M_Qualified_U8X)
	               {
	               /* Check whether the mode is counting mode */
	               if (V_StatusFlags_U8R&M_ModeCounting_U8X)
	                  {
	                  /* EasyCASE ( 222
	                     Counting Mode */
	                  if (/*Check whether correction count >3 in Counting
	                      Mode*/
	                      s_correctionCount_i8>C_CorrectionCountLimit_U8X)
	                     {
	                     /* Add the step count with Correction count */
	                     gs_stepCount_i32+=(s_correctionCount_i8+C_CountOne_U8X);
	                     /* Reset the correction counter */
	                     s_correctionCount_i8 = C_Clear_U8X;
	                     }
	                  else
	                     {
	                     /* Increment the step count */
	                      gs_stepCount_i32++;
	                     }
	                  /* EasyCASE ) */
	                  }
	               else
	                  {
	                  /*Check whether current mode is Detection Mode*/
	                  /* EasyCASE ( 223
	                     Detection Mode */
	                  if (V_StatusFlags_U8R&M_ModeDetection_U8X)
	                     {
	                     if (/*Correction count is added to interstep count
	                         whwn correction count >3 in detection mode*/
	                         s_correctionCount_i8>C_CorrectionCountLimit_U8X)
	                        {
	                        /* Increment the step count */
	                        s_interStepCount_i8+=(s_correctionCount_i8+1);
	                        /* Reset the correction counter */
	                        s_correctionCount_i8 = C_Clear_U8X;
	                        }
	                     else
	                        {
	                        /* Increment the step count */
	                         s_interStepCount_i8++;
	                        }
	                     if (/*When interstep count > 9 mode changed to counting in case if Robustness feature enabled
	                         When interstep count > 3 mode changed to counting in case if Robustness feature disabled*/
	                         ((s_interStepCount_i8 > C_InterStepCountLimit_U8X)&&
	                         ((V_StatusFlags_U8R & M_DisableRobustness_U8X)==0))||
	                         ((s_interStepCount_i8 > C_InterStepCountLimitNoRobustness)
	                         &&((V_StatusFlags_U8R & M_DisableRobustness_U8X)
	                         ==M_DisableRobustness_U8X)))
	                        {
	                        /* Set the mode to MODE_COUNTING */
	                        V_StatusFlags_U8R|=M_ModeCounting_U8X;
	                        V_StatusFlags_U8R&=~M_ModeDetection_U8X;
	                        /* Increment the step */
	                        gs_stepCount_i32+=(s_interStepCount_i8+s_correctionCount_i8);
	                        /* Reset the interstep counter */
	                        s_interStepCount_i8 = C_Clear_U8X;
	                        /* Reset the correction counter */
	                         s_correctionCount_i8 = C_Clear_U8X;
	                        }
	                     }
	                  /* EasyCASE ) */
	                  }
	               }
	            else
	               {
	               /* EasyCASE ( 221
	                  Correction Count */
	               if (/*Check whether Step is unqualified*/
	                   V_StatusFlags_U8R & M_UnQualified_U8X)
	                  {
	                  /* Increment the correction count */
	                  s_correctionCount_i8++;
	                  }
	               /* EasyCASE ) */
	               }
	            }
	         else
	            {
	            /* EasyCASE ( 219
	               Error Count */
	            if (/*Error count is incremented if the step is not
	                 valid and not due to noise*/
	                (composite_i16>C_SensorNoiseLevel_U8X))
	               {
	               /*Error count is incremented*/
	               v_ErrorCount_u8++;
	               }
	            if (/*When the error count becomes greater than 3 the
	                temporary counts are cleared*/
	                v_ErrorCount_u8>C_ErrorCountLimit_U8X)
	               {
	               /*The mode changed to detection and counts are cleared*/
	               V_StatusFlags_U8R|=M_ModeDetection_U8X;
	               V_StatusFlags_U8R&=~M_ModeCounting_U8X;
	               v_ErrorCount_u8=C_Clear_U8X;
	               s_correctionCount_i8=C_Clear_U8X;
	               s_interStepCount_i8=C_Clear_U8X;
	               V_StatusFlags_U8R &=~(M_Qualified_U8X|M_UnQualified_U8X);
	               s_ModeTimer_i8 = C_Clear_U8X;
	               }
	            /* EasyCASE ) */
	            }
	         /* EasyCASE ( 224
	            Step to Step Count Updation */
	         if (/*Count step to step is updated if the
	             trend change is not due to noise*/
	             composite_i16>C_SensorNoiseLevel_U8X)
	            {
	            /* Update the last, secondlast and thridlast count variables */
	            s_countStepToStepPrev2_i16 = s_countStepToStepPrev1_i16;
	            s_countStepToStepPrev1_i16 = gs_countStepToStep_i16;
	            gs_countStepToStep_i16 = C_Clear_U8X;
	            }
	         /* EasyCASE ) */
	         /* EasyCASE ) */
	         /* Reset the sample count for cycle */
	         s_sampleCountForCycle_i16 = C_Clear_U8X;
	         }
	      }
	   /* EasyCASE ) */
	   /*Current status are stored*/
	   v_PreStatusFlags_u8r=V_StatusFlags_U8R;
	   /* return the composite value */
	   return composite_i16;
   }
/* EasyCASE ) */
/* EasyCASE ( 9
   getActivity */
/* EasyCASE F */
/**
  \brief This function will Return the nature of the step \n
   Whether the step is of Jogg(0x12)/Walk(0x11)/Slow Walk(0x10) nature\n
  \param None
  \return Step Nature
*/

unsigned char getActivity(void)
   {
   /*
   **
   **********************************************************************************
     Function Name : unsigned char getActivity(void)
     Input         : None
     Output        : None
   
     Detailed Description:
       This function will Return the Activity of the Pedometer.
   **********************************************************************************
   **
   */
   char v_Activity_u8r;
   if (V_Activity_U8&M_Walk_U8X)
      {
      /*Current activity is walk*/
      v_Activity_u8r=0x11;
      }
   else
      {
      if (V_Activity_U8&M_SlowWalk_U8X)
         {
         /*Current activity is slow walk*/
         v_Activity_u8r=0x10;
         }
      else
         {
         if (V_Activity_U8&M_Jog_U8X)
            {
            /*Current activity is jog*/
            v_Activity_u8r=0x12;
            }
         else
            {
            v_Activity_u8r=C_Clear_U8X;
            }
         }
      }
   return (v_Activity_u8r);
   }
/* EasyCASE ) */
/* EasyCASE ( 94
   InitAlgo */
/* EasyCASE F */
/**
  \brief This function will initialze the variables that are used in the
  Pedometer Algorithm. It should be called in Power On Init.0 is passed as parameter for 2G,
  1 for 4G and 2 for 8G\n
  <b>Calling instance:<b>\n Call the function after giving a delay (10msec) after power on
  \param unsigned char v_GRange_u8r : Parameter used to set the division factor for threshold.\n
  0-->2G\n
  1-->4G\n
  2-->8G\n
  \return None\n

*/
void InitAlgo()
   {
   /*
   **
   **********************************************************************************
     Function Name  : void InitAlgo(void)
     Input          : None
     Output         : None
     Scope          : Global
   
     Detailed Description:
           This function will initialze the variables that are used in the Algorithm.
   **********************************************************************************
   **
   */
       /* Reset the activity as 0 */
       V_Activity_U8 = C_Clear_U8X;
       /* Reset the step count */
       gs_stepCount_i32 = C_Clear_U8X;
       /* Set the Flag so that algo starts fresh */
       V_StatusFlags_U8R = C_Clear_U8X;
       V_StatusFlags_U8R |= (M_ModeDetection_U8X|M_AlgoReset_U8X);
       V_DivideFactor_U8R=0;
       /*Default lower limit set as robust*/
       V_LazyWalkLowerLimit_U8R=LAZY_WALKING_LOWER_LIMIT_Robust;
   }
/* EasyCASE ) */
/* EasyCASE ( 208
   Enable Robustness */
/* EasyCASE F */
/**
  \brief This function will start the Pedometer Algorithm with robustness
  feature enabled.By default robustness feature will be there in the algorithm.
  If any time the robustness feature is disabled then user need to call this
  functionto enable the robustness feature. 
  
  \param None
  \return None
*/

void enableRobustness()
   {
   /*
   **
   *********************************************************************************
     Function Name : void enableRobustness()
   
     Input         : None
     Output        : None
     Scope         : Global
   
     Detailed Description:
     This function will start the Pedometer Algorithm with robustness
     feature enabled.By default robustness feature will be there in the algorithm.
     If any time the robustness feature is disabled then user need to call this
     function to enable the robustness feature.
   **********************************************************************************  
   **
   */
    V_StatusFlags_U8R&=~(M_DisableRobustness_U8X);
    /*Lower threshold for robust mode*/
    V_LazyWalkLowerLimit_U8R=LAZY_WALKING_LOWER_LIMIT_Robust;
   }
/* EasyCASE ) */
/* EasyCASE ( 209
   Disable Robustness */
/* EasyCASE F */
/**
  \brief This function will start the Pedometer Algorithm with robustness
  feature disabled.By default robustness feature will be there in the algorithm.
  If any time the robustness feature need to be disabled then user need to call this
  function 
  
  \param None
  \return None
*/

void disableRobustness()
   {
   /*
   **
   *********************************************************************************
     Function Name : void disableRobustness()
   
     Input         : None
     Output        : None
     Scope         : Global
   
     Detailed Description:
     This function will start the Pedometer Algorithm with robustness
     feature disabled.By default robustness feature will be there in the algorithm.
     If any time the robustness feature need to be disabled then user need to call this
     function 
   **********************************************************************************  
   **
   */
    V_StatusFlags_U8R|=(M_DisableRobustness_U8X);
     /*Lower threshold for  non robust mode*/
    V_LazyWalkLowerLimit_U8R=LAZY_WALKING_LOWER_LIMIT_NoRobust;
   }
/* EasyCASE ) */
/* EasyCASE ) */
/* EasyCASE ( 45
   Local Functions */
/* EasyCASE ( 2
   getAbsoluteShort */
/* EasyCASE F */
static short getAbsoluteShort(short f_val_i16)
   {
   /*
   **
   *********************************************************************************
     Function Name : static short getAbsoluteShort(short f_val_i16)
     Input         : short f_val_i16
     Output        : positive f_val_i16
     Scope         : Local
   
     Detailed Description:
   
     Variables:
        short f_val_i16:
          This is the variable whose absolute short has to be returned
   
     Description:
          The function recieves f_val_i16 as input and the function always return the
         positive value of f_val_i16
   
   *********************************************************************************
   **
   */
           /* Return the positive value of the passed variable */
   return (f_val_i16 < 0)? -f_val_i16 : f_val_i16;
   }
/* EasyCASE ) */
/* EasyCASE ( 186
   trendFinder */
/* EasyCASE F */
static void trendFinder(short f_composite_i16, short* f_optimalComposite_i16p)
   {
   /*
   **
   ***************************************************************************************************
     Function Name   : static char trendFinder(short f_composite_i16, short* f_optimalComposite_i16p)
     Input           : short f_composite_i16
                       short* f_optimalComposite_i16p
     Output          : Returns 1 if the trend is positive
                       Returns -1 if the trend is negative
                       Returns 0 if there is no trend change
     Scope           : Local
   
     Detailed Description:
       Variables:
         short f_composite_i16:
                   This parameter is the composite value whose trend has to be
                   found out.
         short* f_optimalComposite_i16p:
                   The address at which the trend of the passed composite value is
                   stored
       Output :Returns 1 if the trend is positive
               Returns -1 if the trend is negative
               Returns 0 if there is no trend change
   
   
     Description:
         This function verifies if there is trend change from the given input and
         the previous ones and returns 1 or -1 if there is positive or negative
         trend change and returns 0 if there is no trend change.
   ****************************************************************************************************
   **
   */
   
           /* Holds the last composite value */
           static signed short     s_compositePrev1_i16 = -1;
           /* Holds the second last composite value */
           static signed short     s_compositePrev2_i16 = -1;
           /* Holds the current trend */
           static signed char      s_currTrend_i8 = -1;
           /* Holds the Change in the trend */
         V_StatusFlags_U8R &=~(M_NegativeTrend_U8X|M_PositiveTrend_U8X);
           /* Check whether the current trend is positive */
   if (s_currTrend_i8 == 1)
      {
      /* check whether there is a trend change between *
       * the present and the previous composite values */
      if (f_composite_i16 < s_compositePrev1_i16 &&
               f_composite_i16 < s_compositePrev2_i16)
         {
         /* Set the current trend as negative */
         s_currTrend_i8 = -1;
         /* Set the change in trend as negative */
         V_StatusFlags_U8R |= M_NegativeTrend_U8X;
         /* Return the optimal composite value */
         *f_optimalComposite_i16p = (s_compositePrev1_i16 > s_compositePrev2_i16)?
                 s_compositePrev1_i16 : s_compositePrev2_i16;
         }
      /* If the current trend is negative */
      }
   else
      {
      /* check whether there is a trend change between *
       * the present and the previous composite values */
      if (f_composite_i16 > s_compositePrev1_i16 &&
               f_composite_i16 > s_compositePrev2_i16)
         {
         /* Set the current trend as Positive */
         s_currTrend_i8 = 1;
         /* Set the change in trend as Positive */
         V_StatusFlags_U8R |= M_PositiveTrend_U8X;
         /* Return the optimal composite value */
         *f_optimalComposite_i16p = (s_compositePrev1_i16 < s_compositePrev2_i16)?
                 s_compositePrev1_i16 : s_compositePrev2_i16;
         }
      }
   /* Update the second last composite value */
   s_compositePrev2_i16 = s_compositePrev1_i16;
   /* Update the last composite values */
   s_compositePrev1_i16 = f_composite_i16;
   /* Return the Change in trend */
   }


